import type { AxiosInstance, AxiosRequestConfig } from 'axios'
import type {
  HttpError,
  HttpRequestConfig,
  HttpResponse,
  RequestMethods,
} from './type'
import { IPAREA, LANGUAGE, TOKEN } from '@/store/const'
import { storageLocal } from '@wxcn/utils'
import axios from 'axios'
import { isEnv, isLocale } from '../env'
import { languageDefault } from '../i18n'

export const baseURL
  = isEnv('production') && !isLocale()
    ? window.globalConfig.apiUrl
    : import.meta.env.VITE_API_URL
const defaultConfig: AxiosRequestConfig = {
  baseURL,
  headers: {
    'Content-Type': 'application/json; charset=utf-8',
    'appmodel': 'xxx',
  },
}
class Http {
  constructor() {
    this.httpInterceptorsRequest()
    this.httpInterceptorsResponse()
  }
  // 初始化配置对象
  // private static initConfig: HttpRequestConfig = {};

  // 保存当前Axios实例对象
  private static axiosInstance: AxiosInstance = axios.create(defaultConfig)

  // 请求拦截
  private httpInterceptorsRequest(): void {
    const instance = Http.axiosInstance
    instance.interceptors.request.use(
      (config: HttpRequestConfig) => {
        const $config = config
        config.headers = Object.assign(config.headers || {}, {
          'Accept-language': storageLocal.getItem(LANGUAGE)?.value || languageDefault.value,
          'ClientType': 2,
        })
        if (!Array.isArray(config.data)) {
          config.data = {
            ...config.data,
            language: storageLocal.getItem(LANGUAGE) || languageDefault.value,
          }
        }
        const token = storageLocal.getItem(TOKEN)
        if (token)
          config.headers.authorization = token.Token // `Bearer ${token}`;
        return $config
      },
      (error) => {
        return Promise.reject(error)
      },
    )
  }

  // 响应拦截
  private httpInterceptorsResponse(): void {
    const instance = Http.axiosInstance
    instance.interceptors.response.use(
      (response: HttpResponse) => {
        // const $config = response.config;
        storageLocal.setItem(IPAREA, response.headers.pragma || 'default')
        return response.data
      },
      (error: HttpError) => {
        const $error = error
        $error.isCancelRequest = axios.isCancel($error)
        // if ($error.response?.status === 401 && !location.href.includes("/sign/in")) {
        //   window.open("/sign/in", "_self");
        // }

        // 所有的响应异常 区分来源为取消请求/非取消请求
        $error.errData = $error.response?.data as HttpError['errData']
        return Promise.reject($error)
      },
    )
  }

  // 通用请求工具函数
  public request<R>(
    method: RequestMethods,
    url: string,
    param?: AxiosRequestConfig,
    axiosConfig?: HttpRequestConfig,
  ): Promise<R> {
    const config = {
      method,
      url,
      ...param,
      ...axiosConfig,
    } as HttpRequestConfig

    // 单独处理自定义请求/响应回掉
    return new Promise((resolve, reject) => {
      Http.axiosInstance
        .request(config)
        .then((response: any) => {
          resolve(response)
        })
        .catch((error) => {
          reject(error)
        })
    })
  }

  // 单独抽离的post工具函数
  public post<P, R>(
    url: string,
    params?: P,
    config?: HttpRequestConfig,
  ): Promise<R> {
    return this.request<R>('post', url, { data: params }, config)
  }

  // 单独抽离的get工具函数
  public get<P, R>(
    url: string,
    params?: P,
    config?: HttpRequestConfig,
  ): Promise<R> {
    return this.request<R>('get', url, { params }, config)
  }
}

export const http = new Http()
